package fr.gedos.ged.analyser.recognition.adapter.beans;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import fr.gedos.ged.analyser.recognition.adapter.exceptions.PictureNotWellWritingException;
import fr.gedos.ged.analyser.recognition.adapter.interfaces.ImageSplitter;
import fr.gedos.ged.analyser.recognition.adapter.interfaces.PictureCleaner;


/**
 * This class permit to split an Image to extract SubImage.
 * 
 * @author rastafire
 * 
 */
public class PictureSplitterBean implements ImageSplitter {

    /** The cleaner which will clean sub pictures. */
    private PictureCleaner cleaner;

    /**
     * Simple constructor.
     * 
     * @param cleanerImpl
     *            - A cleaner which permit to clean up the picture
     */
    public PictureSplitterBean(PictureCleaner cleanerImpl) {
        this.cleaner = cleanerImpl;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * fr.gedos.ged.classifier.recognition.adapter.interfaces.ImageSplitter#getSubPicture(java.io
     * .File, java.awt.Rectangle)
     */
    public File getSubPicture(File fileToProcess, Rectangle area) throws IOException,
            PictureNotWellWritingException {
        BufferedImage image = loadImage(fileToProcess);
        // get bounds for sub picture
        int x = (int) area.getX() + 1;
        int y = (int) area.getY() + 1;
        int width = (int) area.getWidth() + 1;
        int height = (int) area.getHeight() + 1;
        // getSubImage and write it in a new tmp file
        BufferedImage subImage = image.getSubimage(x, y, width, height);
        String[] splittedFileName = fileToProcess.getName().split("\\.");
        String fileExtension = splittedFileName[splittedFileName.length - 1];
        int sizeExt = splittedFileName[splittedFileName.length - 1].length();
        String absoluteFileToProcessPath = fileToProcess.getAbsolutePath();
        String fileExtractedPath = absoluteFileToProcessPath.substring(0,
                absoluteFileToProcessPath.length() - sizeExt - 1)
                + "_tmp." + fileExtension;
        File fileExtracted = new File(fileExtractedPath);
        boolean successOfWrite = writeImage(fileExtracted, subImage, fileExtension);
        if (!successOfWrite) {
            throw new PictureNotWellWritingException("SubPictures can nor be saved!");
        }

        // clean the sub picture -> will no create a new file but will erase the sub picture file
        cleaner.cleanPicture(fileExtracted);
        return fileExtracted;
    }

    /**
     * Permit to load an Image Object from a picture File.
     * 
     * @param image
     *            - the input file
     * @return - the BufferedImage extracted from the picture file
     * @throws IOException
     */
    protected BufferedImage loadImage(File image) throws IOException {
        BufferedImage bimg = ImageIO.read(image);
        return bimg;
    }

    /**
     * Permit to write a BufferedImage in a file.
     * 
     * @param output
     *            - The file in which we must write picture
     * @param pictureToWrite
     *            - The picture to write
     * @return - true if success of save picture action, false else
     * @throws IOException
     */
    protected boolean writeImage(File output, BufferedImage pictureToWrite, String fileExt)
            throws IOException {
        boolean success = ImageIO.write(pictureToWrite, fileExt, output);
        return success;
    }
}
